package com.erikpasternak.vader;

import java.util.ArrayList;
import java.util.HashSet;

import android.content.Context;
import android.database.Cursor;
import android.text.TextUtils;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.ArrayAdapter;
import android.widget.Filter;
import android.widget.TextView;

import com.erikpasternak.vader.DrinksAdapter.Drink;

public class DrinksAdapter extends ArrayAdapter<Drink> {
    private static final String TAG = "DrinksAdapter";

    private final LayoutInflater mHelium;
    private long mSelected;
    private final SharedPrefsHelper mPrefsHelper;
    private final HashSet<String> mStockedIngredients = new HashSet<String>(
            SharedPrefsHelper.MAX_INGREDIENTS);
    private final ArrayList<Drink> mAllDrinks;
    private final ArrayList<Drink> mDisplayedDrinks;

    protected final static int[] INGREDIENT_QUANTITY_INDICES = new int[] {
            DrinkDbHelper.INDEX_Q1, DrinkDbHelper.INDEX_Q2, DrinkDbHelper.INDEX_Q3,
            DrinkDbHelper.INDEX_Q4, DrinkDbHelper.INDEX_Q5, DrinkDbHelper.INDEX_Q6,
            DrinkDbHelper.INDEX_Q7, DrinkDbHelper.INDEX_Q8
    };
    protected final static int[] INGREDIENT_NAME_INDICES = new int[] {
            DrinkDbHelper.INDEX_I1, DrinkDbHelper.INDEX_I2, DrinkDbHelper.INDEX_I3,
            DrinkDbHelper.INDEX_I4, DrinkDbHelper.INDEX_I5, DrinkDbHelper.INDEX_I6,
            DrinkDbHelper.INDEX_I7, DrinkDbHelper.INDEX_I8
    };
    final static int[] INGREDIENT_VIEW_IDS = new int[] {
            R.id.ingredient1, R.id.ingredient2, R.id.ingredient3, R.id.ingredient4,
            R.id.ingredient5, R.id.ingredient6, R.id.ingredient7, R.id.ingredient8
    };

    public class Drink {
        public ArrayList<Ingredient> mIngredients = new ArrayList<Ingredient>();
        public String mName;
        public String mComments;
        public int mNumIngredients;
        public int mAvailIngredients;
        public long mId;
        public boolean mFull = false;

        public Drink(Cursor cursor) {
            mId = cursor.getLong(DrinkDbHelper.INDEX_ID);

            mNumIngredients = 0;
            mAvailIngredients = 0;

            StringBuilder bob = new StringBuilder("Ingredients: ");
            for (int i = 0; i < SharedPrefsHelper.MAX_INGREDIENTS; i++) {
                String ing = cursor.getString(INGREDIENT_NAME_INDICES[i]);
                int amount = cursor.getInt(INGREDIENT_QUANTITY_INDICES[i]);
                if (!TextUtils.isEmpty(ing) && amount > 0) {
                    bob.append(ing).append("(").append(amount / 2.0f).append(" oz)").append(", ");
                    mIngredients.add(new Ingredient(ing, amount));
                    mNumIngredients++;
                    if (mStockedIngredients.contains(ing)) {
                        mAvailIngredients++;
                    }
                }
            }
            bob.append("\n\nComments: ").append(cursor.getString(DrinkDbHelper.INDEX_COMMENT));
            mComments = bob.toString();

            bob.setLength(0);
            bob.append(cursor.getString(DrinkDbHelper.INDEX_NAME));
            bob.append(" (").append(mAvailIngredients).append("/").append(mNumIngredients)
                    .append(")");
            mName = bob.toString();

            if (mAvailIngredients == mNumIngredients) {
                mFull = true;
            }
        }

        @Override
        public String toString() {
            return mName;
        }
    }

    public class Ingredient {
        public String name;
        public int amount;

        public Ingredient(String name, int amount) {
            this.name = name;
            this.amount = amount;
        }
    }

    private final Filter mFilter = new Filter() {

        @Override
        protected FilterResults performFiltering(CharSequence arg0) {
            String filterString = arg0.toString().toLowerCase();
            ArrayList<Drink> drinks = new ArrayList<Drink>();
            for (Drink d : mAllDrinks) {
                if (d.mName.toLowerCase().contains(filterString)) {
                    drinks.add(d);
                }
            }
            FilterResults result = new FilterResults();
            result.count = drinks.size();
            result.values = drinks;
            return result;
        }

        @Override
        protected void publishResults(CharSequence arg0, FilterResults arg1) {
            mDisplayedDrinks.clear();
            mDisplayedDrinks.addAll((ArrayList<Drink>) arg1.values);
            DrinksAdapter.this.notifyDataSetChanged();
        }

    };

    public DrinksAdapter(Context context, Cursor c, boolean showAll) {
        super(context, R.layout.drink_item);
        mHelium = (LayoutInflater) context.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
        mPrefsHelper = new SharedPrefsHelper(context);
        String[] ingredients = mPrefsHelper.getIngredients();
        for (int i = 0; i < ingredients.length; i += 2) {
            mStockedIngredients.add(ingredients[i]);
        }

        mDisplayedDrinks = new ArrayList<Drink>(c.getCount());
        mAllDrinks = new ArrayList<Drink>(c.getCount());
        c.moveToPosition(-1);
        while (c.moveToNext()) {
            Drink drink = new Drink(c);
            // TODO make this toggleable after creation
            if (showAll || drink.mFull) {
                mAllDrinks.add(new Drink(c));
            }
        }
        mDisplayedDrinks.addAll(mAllDrinks);
    }

    @Override
    public View getView(int position, View view, ViewGroup parent) {
        TextView item;
        if (view != null) {
            item = (TextView) view;
        } else {
            item = (TextView) mHelium.inflate(R.layout.drink_item, null);
        }
        Drink drink = mDisplayedDrinks.get(position);
        item.setText(drink.mName);
        if (drink.mId == mSelected) {
            item.setBackgroundColor(0xFFFFFFFF);
            item.setTextColor(0xFF000000);
        } else {
            item.setTextColor(0xFFFFFFFF);
            int missing = drink.mNumIngredients - drink.mAvailIngredients;
            if (missing > 2) {
                item.setBackgroundColor(0xff990000);
            } else if (missing > 0) {
                item.setBackgroundColor(0xffC09514);
            } else {
                item.setBackgroundColor(0xff006600);
            }
        }
        return item;
    }

    public void setSelection(long selection) {
        mSelected = selection;
        notifyDataSetChanged();
    }

    public long getSelection() {
        return mSelected;
    }

    @Override
    public Drink getItem(int position) {
        return mDisplayedDrinks.get(position);
    }

    @Override
    public long getItemId(int position) {
        return mDisplayedDrinks.get(position).mId;
    }

    @Override
    public int getCount() {
        return mDisplayedDrinks.size();
    }

    @Override
    public boolean hasStableIds() {
        return true;
    }

    @Override
    public Filter getFilter() {
        return mFilter;
    }
}
